<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>强缓存和协商缓存</title>
	</head>
	<body>
		<script>
			//         缓存可分为强缓存和协商缓存。
			//    浏览器进行资源请求时，会判断response headers是否命中强缓存，如果命中，直接从本地读取缓存，不会向服务器发送请求，
			//    当强缓存没有命中时，会发送请求到服务端，判断协商缓存是否命中，如果命中，服务器将请求返回，不会返回资源，告诉浏览器从本地读取缓存。如何不命中，服务器直接返回资源
			//    区别： 强缓存命中，不会请求服务器，直接请求缓存；协商缓存命中，会请求服务器，不会返回内容，然后读取缓存；

			// 强缓存又分为Expires 和 Cache-Control
			// Expires,该值是一个GMT时间格式个字符串，浏览器进行第一次请求时，服务器会在返回头部加上Expires，下次请求，如果在这个时间之前则命中缓存，

			// app.get('/', (req, res) => {
			// 	const cssContent = path.join(__dirname, './html/index.html')
			// 	fs.readFile(cssContent, function (err, data) {
			// 		res.setHeader(
			// 			'Expires',
			// 			new Date(Date.now() + 2592000000).toUTCString()
			// 		)
			// 		res.end(data)
			// 	})
			// })
			//             Cache-Control ，该值是利用max-age判断缓存的生命周期，是以秒为单位，如何在生命周期时间内，则命中缓存
			//             app.get('/', (req, res) => {
			//     const cssContent = path.join(__dirname, './html/index.html');
			//     fs.readFile(cssContent, function(err, data) {
			//         res.setHeader("Cache-Control", "max-age=0");
			//         res.end(data);
			//     })
			// });
			//             协商缓存
			// 协商缓存利用Last-Modified , If-Modified-Since 和 ETag , If-None-Match来实现
			// Last-Modified , If-Modified-Since
			// Last-Modified： 表示为为实体头部部分，response返回，表示为资源的最后更新时间

			// If-Modified-Since：通过比较两次的时间判断，资源在请求期间是否有修改，假如没有修改，则命中协商缓存，浏览器从缓存中读取资源，如果没有命中，资源有过修改，返回新的Last-Modified时间和服务器资源
			//     app.get('/', (req, res) => {
			//     const cssContent = path.join(__dirname, './html/index.html')
			//     fs.stat(cssContent, (err, start) => {
			//         if (req.headers['if-modified-since'] === start.mtime.toUTCString()) {
			//             res.writeHead(304, 'Not Modified');
			//             res.end();
			//         } else {
			//             fs.readFile(cssContent, function (err, data) {
			//                 let lastModified = start.mtime.toUTCString();
			//                 res.setHeader('Last-Modified', lastModified);
			//                 res.writeHead(200, 'OK');
			//                 res.end(data);
			//             })
			//         }
			//     })

			// });
			// 复制代码ETag , If-None-Match
			// 有些情况下仅判断最后修改日期来验证资源是否有改动是不够的：
			// 1，存在周期性重写某些资源，但资源实际包含的内容并无变化；
			// 2，被修改的信息并不重要，如注释等；
			// 3，Last-Modified无法精确到毫秒，但有些资源更新频率有时会小于一秒。

			// ETag:为相应头部字段，表示资源内容的唯一标识，随服务器response返回；

			// If-None-Match: 服务器比较请求头中的If-None-Match和当前资源中的etag是否一致，来判断资源是否修改过，如果没有修改，则命中缓存，浏览器从缓存中读取资源，如果修改过，服务器会返回新的etag，并返回资源；
			// app.get('/home', (req, res) => {
			//     const cssContent = path.join(__dirname, './html/index.html')
			//     fs.stat(cssContent, (err, start) => {
			//         let etag = md5(cssContent);
			//         if (req.headers['if-none-match'] === etag) {
			//             res.writeHead(304, 'Not Modified');
			//             res.end();
			//         } else {
			//             fs.readFile(cssContent, function (err, data) {
			//                 res.setHeader('Etag', etag);
			//                 res.writeHead(200, 'OK');
			//                 res.end(data);
			//             })
			//         }
			//     })
			// });
		</script>
	</body>
</html>
